package com.ihisomp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ihisomp.base.Page;
import com.ihisomp.base.Result;
import com.ihisomp.dto.OmpUserDto;
import com.ihisomp.dto.UserRolePathDto;
import com.ihisomp.entity.OmpUser;
import com.ihisomp.entity.OmpUserRole;
import com.ihisomp.mapper.OmpUserMapper;
import com.ihisomp.service.IOmpUserRoleService;
import com.ihisomp.service.IOmpUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ihisomp.service.ISysGetNoService;
import com.ihisomp.util.ComUtil;
import com.ihisomp.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 标题: OmpUserServiceImpl.java
 * 业务描述: 运营管理用户信息 服务实现类
 * 作者: zy
 * 日期: 2021/9/13
 * 版本: V1.0
 */
@Service
public class OmpUserServiceImpl extends ServiceImpl<OmpUserMapper, OmpUser> implements IOmpUserService {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private ISysGetNoService sysGetNoService;

    @Autowired
    private IOmpUserRoleService ompUserRoleService;


    /**
     * 用户登录
     *
     * @param loginName
     * @param password
     * @return
     */
    @Override
    public Result login(String loginName, String password) {
        if (StringUtils.isBlank(loginName) || StringUtils.isBlank(password)) {
            return Result.error("用户账号或密码错误！");
        }
        // 查询用户名是否存在
        OmpUser ompUser = getByLoginName(loginName);
        if (ompUser == null) {
            return Result.error("该用户账号不存在！");
        }
        // 验证用户的使用状态
        if (ompUser.getActiveFlg() == 0) {
            return Result.error("该用户已停用，请联系管理员处理！");
        }
        // 验证错误登录次数
        if (ompUser.getErrorCount() > 3) {
            return Result.error("该用户错误登录次数已超过3次，请联系管理员处理！");
        }
        // 验证密码是否正确
        if (!new BCryptPasswordEncoder().matches(password, ompUser.getPassword())) {
            return Result.build(-1, "密码错误");
        }
        // 生成token
        String jwt = jwtUtil.createJWT(ompUser.getUserKey(), ompUser.getLoginName(), true);
        Map<String, String> map = new HashMap();
        map.put("token", jwt);
        return Result.ok("验证成功", map);
    }

    /**
     * 获取用户信息
     *
     * @param token
     * @return
     */
    @Override
    public Result getUserInfo(String token) {
        Claims claims = jwtUtil.parseJWT(token);
        if (claims == null || StringUtils.isBlank(claims.getSubject())) {
            return Result.error("获取用户信息失败！");
        }
        // 获取用户信息
        OmpUser ompUser = getByLoginName(claims.getSubject());
        if (ompUser == null) {
            return Result.error("用户不存在！");
        }
        // 设置密码
        ompUser.setPassword("");
        // 身份证及电话号码解密
        ompUser.setPhoneNumber(ComUtil.decryptDbField(ompUser.getPhoneNumber()));
        ompUser.setIdNumber(ComUtil.decryptDbField(ompUser.getIdNumber()));
        // 设置角色
        List<String> list = new ArrayList<String>();
        list.add("admin");
        ompUser.setRoles(list);
        return Result.ok("成功获取用户信息", ompUser);
    }

    /**
     * 获取用户角色路径
     *
     * @param userKey
     * @return
     */
    @Override
    public Result getUserPath(String userKey) {
        // 获取用户信息
        OmpUser ompUser = baseMapper.selectById(userKey);
        if (ompUser == null) {
            return Result.error("用户不存在！");
        }
        // 设置密码为空
        ompUser.setPassword("");
        // 查询角色权限路径集合
        List<UserRolePathDto> userPathList = baseMapper.queryUserRolePathList(ompUser.getUserKey());
        if (userPathList.size() <= 0) {
            return Result.error("该用户没有对应的角色路径！");
        }
        // 返回数据集合
        List<UserRolePathDto> pathList = new ArrayList<>();
        // 查找一级菜单路径
        for (int i = 0; i < userPathList.size(); i++) {
            // 一级菜单没有pid
            if (StringUtils.isBlank(userPathList.get(i).getPid())) {
                pathList.add(userPathList.get(i));
            }
        }
        // 递归查询子菜单
        // 为一级菜单设置子菜单，getChild是递归调用的
        for (UserRolePathDto path : pathList) {
            path.setChildPaths(getChild(path.getId(), userPathList));
        }
        Map<String, List> map = new HashMap<>();
        map.put("path", pathList);
        return Result.ok(map);
    }

    /**
     * 递归查找子菜单
     *
     * @param id
     * @param rootPath
     * @return
     */
    private List<UserRolePathDto> getChild(String id, List<UserRolePathDto> rootPath) {
        // 子菜单
        List<UserRolePathDto> childList = new ArrayList<>();
        for (UserRolePathDto path : rootPath) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (StringUtils.isNotBlank(path.getPid())) {
                if (path.getPid().equals(id)) {
                    childList.add(path);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (UserRolePathDto path : childList) {// 没有url子菜单还有子菜单
            if (StringUtils.isNotBlank(path.getUrl()) && path.getType().intValue() != 3) {
                // 递归
                path.setChildPaths(getChild(path.getId(), rootPath));
            }
        } // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }

    /**
     * 更新登录日志
     *
     * @param ompUserDto
     * @return
     */
    @Override
    public Result updateLoginInfo(OmpUserDto ompUserDto) {
        OmpUser ompUser = getByLoginName(ompUserDto.getLoginName());
        if (ompUser == null) {
            return Result.error("用户不存在！");
        }
        // 更新登录日志
        // 重置错误次数
        ompUser.setErrorCount(0);
        // 累计登录次数
        ompUser.setLoginNum(ompUser.getLoginNum() + 1);
        // 本日登录次数
        String sysTime = ComUtil.getDateTimeString();
        if (ompUser.getLastTime() == null || "".equals(ompUser.getLastTime())) {
            ompUser.setLoginNumToday(1);
        } else if (sysTime.substring(0, 8).equals(ompUser.getLastTime().substring(0, 8))) {
            ompUser.setLoginNumToday(ompUser.getLoginNumToday() + 1);
        } else {
            ompUser.setLoginNumToday(1);
        }
        // 登录IP
        ompUser.setLastIp(ompUserDto.getLastIp());
        // 登录时间
        ompUser.setLastTime(sysTime);
        if (baseMapper.updateById(ompUser) > 0) {
            return Result.ok("更新登录日志成功！");
        }
        return Result.error("更新登录日志失败！");
    }

    /**
     * 登录错误
     *
     * @param loginName
     * @return
     */
    @Override
    public Result loginError(String loginName) {
        if (baseMapper.loginError(loginName) > 0) {
            return Result.ok("更新登录错误次数成功！");
        }
        return Result.error("更新登录错误次数失败！");
    }

    /**
     * 检核密码
     *
     * @param ompUserDto
     * @return
     */
    @Override
    public Result checkPwd(OmpUserDto ompUserDto) {
        if (ompUserDto == null || StringUtils.isEmpty(ompUserDto.getPassword())) {
            return Result.error("原密码不能为空！");
        }
        OmpUser ompUser = baseMapper.selectById(ompUserDto.getUserKey());
        // 验证密码是否正确
        if (!new BCryptPasswordEncoder().matches(ompUserDto.getPassword(), ompUser.getPassword())) {
            return Result.error("原密码错误");
        }
        return Result.ok();
    }

    /**
     * 修改密码
     *
     * @param ompUserDto
     * @return
     */
    @Override
    public Result updatePwd(OmpUserDto ompUserDto) {
        if (ompUserDto == null || StringUtils.isEmpty(ompUserDto.getPassword())) {
            return Result.error("新密码不能为空！");
        }
        OmpUser ompUser = baseMapper.selectById(ompUserDto.getUserKey());
        String pwd = new BCryptPasswordEncoder().encode(ompUserDto.getPassword());
        ompUser.setPassword(pwd);
        int i = baseMapper.updateById(ompUser);
        if (i < 1) {
            return Result.error("密码修改失败！");
        }
        return Result.ok();
    }

    /**
     * 新增用户信息
     *
     * @param ompUserDto
     * @return
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
    @Override
    public Result add(OmpUserDto ompUserDto) {
        // 判断用户名及密码不能为空
        if (StringUtils.isBlank(ompUserDto.getLoginName())) {
            return Result.error("用户账号不能为空！");
        }
        if (StringUtils.isBlank(ompUserDto.getPassword())) {
            return Result.error("用户密码不能为空！");
        }
        // 判断用户角色不能为空
        if (ompUserDto.getRoles() == null || ompUserDto.getRoles().size() <= 0) {
            return Result.error("用户角色不能为空！");
        }
        // 查询用户名是否存在
        if (getByLoginName(ompUserDto.getLoginName()) != null) {
            return Result.error("该用户账号已经存在！");
        }
        // 新增用户信息
        OmpUser ompUser = new OmpUser();
        BeanUtils.copyProperties(ompUserDto, ompUser);
        String userKey = sysGetNoService.getSysNo("t_omp_user");
        ompUser.setUserKey(userKey);
        // 密码加密
        ompUser.setPassword(new BCryptPasswordEncoder().encode(ompUserDto.getPassword()));
        // 身份证号加密
        ompUser.setIdNumber(ComUtil.encryptDbField(ompUserDto.getIdNumber()));
        // 电话号码加密
        ompUser.setPhoneNumber(ComUtil.encryptDbField(ompUserDto.getPhoneNumber()));
        ompUser.setErrorCount(0);
        ompUser.setLoginNum(0);
        ompUser.setLoginNumToday(0);
        ompUser.setActiveFlg(1);
        // 新增用户信息
        if (baseMapper.insert(ompUser) > 0) {
            // 新增用户角色
            OmpUserRole ompUserRole = new OmpUserRole();
            ompUserRole.setUserKey(userKey);
            for (int i = 0; i < ompUserDto.getRoles().size(); i++) {
                ompUserRole.setUserRoleKey(ComUtil.createPrimaryKey());
                ompUserRole.setRoleKey(ompUserDto.getRoles().get(i));
                if (!ompUserRoleService.save(ompUserRole)) {
                    return Result.error("新增用户角色失败！");
                }
            }
        } else {
            return Result.error("新增用户角色失败！");
        }
        return Result.ok();
    }

    /**
     * 更新用户信息
     *
     * @param userKey
     * @param ompUserDto
     * @return
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
    @Override
    public Result update(String userKey, OmpUserDto ompUserDto) {
        OmpUser ompUser = baseMapper.selectById(userKey);
        if (ompUser == null) {
            return Result.error("未查询到用户信息！");
        }
        // 实体类赋值
        ompUser.setUserName(ompUserDto.getUserName());
        ompUser.setPy(ompUserDto.getPy());
        ompUser.setSexKey(ompUserDto.getSexKey());
        ompUser.setBirthday(ompUserDto.getBirthday());
        // 身份证号加密
        ompUser.setIdNumber(ComUtil.encryptDbField(ompUserDto.getIdNumber()));
        // 电话号码加密
        ompUser.setPhoneNumber(ComUtil.encryptDbField(ompUserDto.getPhoneNumber()));
        ompUser.setSeqNo(ompUserDto.getSeqNo());
        ompUser.setIntroduction(ompUserDto.getIntroduction());
        ompUser.setAvatar(ompUserDto.getAvatar());
        if (baseMapper.updateById(ompUser) > 0) {
            // 判断是否更新角色
            OmpUserRole ompUserRole = new OmpUserRole();
            ompUserRole.setUserKey(userKey);
            // 删除用户角色
            if (ompUserRoleService.deleteByUserKey(userKey) < 0) {
                return Result.error("删除用户角色失败！");
            }
            if (ompUserDto.getRoles() != null) {
                // 新增用户角色
                for (int i = 0; i < ompUserDto.getRoles().size(); i++) {
                    ompUserRole.setUserRoleKey(ComUtil.createPrimaryKey());
                    ompUserRole.setRoleKey(ompUserDto.getRoles().get(i));
                    if (!ompUserRoleService.save(ompUserRole)) {
                        return Result.error("新增用户角色失败！");
                    }
                }
            }
            return Result.ok();
        } else {
            return Result.error("更新用户信息失败！");
        }
    }

    /**
     * 查询方法
     *
     * @param userKey
     * @return
     */
    @Override
    public Result get(String userKey) {
        OmpUserDto ompUserDto = new OmpUserDto();
        BeanUtils.copyProperties(baseMapper.selectById(userKey), ompUserDto);
        // 身份证号解密
        ompUserDto.setIdNumber(ComUtil.decryptDbField(ompUserDto.getIdNumber()));
        // 电话号码解密
        ompUserDto.setPhoneNumber(ComUtil.decryptDbField(ompUserDto.getPhoneNumber()));
        ompUserDto.setRoles(ompUserRoleService.getRoleByUserKey(userKey));
        return Result.ok(ompUserDto);
    }

    /**
     * 分页查询
     *
     * @param page
     * @param size
     * @param ompUserDto
     * @return
     */
    @Override
    public Result search(long page, long size, OmpUserDto ompUserDto) {
        if (ompUserDto == null) {
            ompUserDto = new OmpUserDto();
        }
        // 分页查询
        IPage<OmpUser> data = baseMapper.searchPage(new Page<OmpUser>(page, size), ompUserDto);
        return Result.ok(data);
    }

    /**
     * 更新用户状态
     *
     * @param userKey
     * @param activeFlg
     * @return
     */
    @Override
    public Result updateStatus(String userKey, int activeFlg) {
        OmpUser ompUser = baseMapper.selectById(userKey);
        if (ompUser == null) {
            return Result.error("无查询用户信息");
        }
        if (activeFlg == 0) {
            ompUser.setActiveFlg(1);
        } else {
            ompUser.setActiveFlg(0);
        }
        if (baseMapper.updateById(ompUser) > 0) {
            return Result.ok();
        }
        return Result.error("更新用户状态失败！");
    }

    /**
     * 查询门户用户名是否存在
     *
     * @param loginName
     * @return
     */
    private OmpUser getByLoginName(String loginName) {
        QueryWrapper<OmpUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("login_name", loginName);
        return baseMapper.selectOne(queryWrapper);
    }


}
